class Array
  # Matches elements of a to elements of b and passes each pair to a block.
  # If an element of a has no match in b or vice versa, nil is passed.
  # Assumes no duplicates in either array.
  def match(arr, &block)
    # create hashes from a and b
    ah = Hash[*self.collect{|x| [x,x]}.flatten]
    bh = Hash[*arr.collect{|x| [x,x]}.flatten]
    
    # matches: loop over a's elements, find them in b, yield, remove from both hashes
    self.each do |x|
      if bh[x]
        block.call(x, bh[x])
        ah.delete(x)
        bh.delete(x)
      end
    end
    
    # a-only's: loop over ah's remaining elements. these had no match in b.
    ah.each_key{|x| block.call(x, nil)}
    
    # b-only's: loop over bh's remaining elements. these had no match in a.
    bh.each_key{|x| block.call(nil, x)}
    
    nil
  end
end